package com.np.rtmpdump5;

import android.graphics.Bitmap;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;

import com.np.library1.BitmapUtil;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

public class BitmapEncoder extends Thread {
    final String TAG = "rtmpdump5_BitmapEncoder";
    MediaCodec mediaCodec;
    BitmapLive bitmapLive;
    int colorFormat = 0;
    int frameRate = 15;
    boolean isRunning = true;
    long timeStamp;
    long startTime;

    public BitmapEncoder(BitmapLive bitmapLive) {
        this.bitmapLive = bitmapLive;
    }

    public void startEncode1() {
        colorFormat = AvcEncoder.getColorFormat();

        MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 100, 100);//宽高要和图片一致，不然会出现绿屏
        //format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 250_000);
        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);

//        //byte[] header_sps = {0, 0, 0, 1, 103, 100, 0, 40, -84, 52, -59, 1, -32, 17, 31, 120, 11, 80, 16, 16, 31, 0, 0, 3, 3, -23, 0, 0, -22, 96, -108};
//        byte[] header_sps = {0, 0, 0, 1, 103, 66, 0, 41, -115, -115, 64, 80, 30, -48, 15, 8, -124, 83, -128};
//        //byte[] header_pps = {0, 0, 0, 1, 104, -18, 60, -128};
//        byte[] header_pps = {0, 0, 0, 1, 104, -54, 67, -56};
//        format.setByteBuffer("csd-0", ByteBuffer.wrap(header_sps));
//        format.setByteBuffer("csd-1", ByteBuffer.wrap(header_pps));
//        format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 300 * 300);
//        format.setInteger("durationUs", 63446722);

        try {
            mediaCodec = MediaCodec.createEncoderByType("video/avc");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mediaCodec.start();

        new Thread(new Runnable() {
            @Override
            public void run() {

                long generateIndex = 0;
                while (isRunning) {
                    Bitmap bitmap = BitmapUtil.generateBitmap();
                    byte[] yuv = AvcEncoder.getNV12(AvcEncoder.getSize(bitmap.getWidth()), AvcEncoder.getSize(bitmap.getHeight()), bitmap, colorFormat);
                    long ptsUsec = AvcEncoder.computePresentationTime(generateIndex, frameRate);

                    try {
                        // 获取可用的输入缓冲区索引
                        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
                        Log.i(TAG, "inputBufferIndex: " + inputBufferIndex);

                        if (inputBufferIndex >= 0) {

                            // 获取输入缓冲区
                            ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
                            inputBuffer.clear();

                            // 将YUV数据填充到输入缓冲区
                            inputBuffer.put(yuv);

                            // 将输入缓冲区提交给编码器
                            mediaCodec.queueInputBuffer(inputBufferIndex, 0, yuv.length, ptsUsec, 0);
                        }

                        generateIndex++;

                        // 获取可用的输出缓冲区索引
                        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                        while (outputBufferIndex >= 0) {
                            Log.i(TAG, "outputBufferIndex: " + outputBufferIndex);

                            ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outputBufferIndex);
                            byte[] outData = new byte[bufferInfo.size];
                            outputBuffer.get(outData);
                            Log.i(TAG, "outData: " + outData);

                            RTMPPackage rtmpPackage = new RTMPPackage(outData, (bufferInfo.presentationTimeUs / 1000) - startTime);
                            bitmapLive.addPackage(rtmpPackage);

                            // 释放输出缓冲区
                            mediaCodec.releaseOutputBuffer(outputBufferIndex, false);

                            // 继续获取下一个输出缓冲区的索引
                            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                        }

                        try {
                            sleep(100);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

//        start();
    }

    public void startEncode2() {
        colorFormat = AvcEncoder.getColorFormat();

        MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 100, 100);//宽高要和图片一致，不然会出现绿屏
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 250_000);
        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);

        try {
            mediaCodec = MediaCodec.createEncoderByType("video/avc");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        mediaCodec.start();

//        List<Bitmap> bitmapList = new ArrayList<>();
//        File directory = new File(Environment.getExternalStorageDirectory().toString());
//        if (directory.isDirectory()) {
//            for (String path : directory.list()) {
//                if (path.endsWith(".jpg")) {
//                    Bitmap bitmap = BitmapUtil.imageToBitmap(path);
//                    bitmapList.add(bitmap);
//                    bitmap = null;
//                }
//            }
//        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                long generateIndex = 0;

                int bitmapIndex = 0;
                while (isRunning) {
//                    if (bitmapIndex >= bitmapList.size())
//                        bitmapIndex = 0;
//                    Bitmap bitmap = bitmapList.get(bitmapIndex++);

                    Bitmap bitmap = BitmapUtil.generateBitmap();
                    byte[] yuv = AvcEncoder.getNV12(AvcEncoder.getSize(bitmap.getWidth()), AvcEncoder.getSize(bitmap.getHeight()), bitmap, colorFormat);
                    long ptsUsec = AvcEncoder.computePresentationTime(generateIndex, frameRate);

                    try {
                        // 获取可用的输入缓冲区索引
                        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
                        Log.i(TAG, "inputBufferIndex: " + inputBufferIndex);

                        if (inputBufferIndex >= 0) {

                            // 获取输入缓冲区
                            ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
                            inputBuffer.clear();

                            // 将YUV数据填充到输入缓冲区
                            inputBuffer.put(yuv);

                            // 将输入缓冲区提交给编码器
                            mediaCodec.queueInputBuffer(inputBufferIndex, 0, yuv.length, ptsUsec, 0);
                        }

                        generateIndex++;

                        // 获取可用的输出缓冲区索引
                        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                        while (outputBufferIndex >= 0) {
                            Log.i(TAG, "outputBufferIndex: " + outputBufferIndex);

                            ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outputBufferIndex);
                            byte[] outData = new byte[bufferInfo.size];
                            outputBuffer.get(outData);
                            Log.i(TAG, "outData: " + outData);

                            RTMPPackage rtmpPackage = new RTMPPackage(outData, (bufferInfo.presentationTimeUs / 1000) - startTime);
                            bitmapLive.addPackage(rtmpPackage);

                            // 释放输出缓冲区
                            mediaCodec.releaseOutputBuffer(outputBufferIndex, false);

                            // 继续获取下一个输出缓冲区的索引
                            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                        }

                        try {
                            sleep(100);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

//        start();
    }

    @Override
    public void run() {
        isRunning = true;
        while (isRunning) {
            if (System.currentTimeMillis() - timeStamp >= 2000) {
                Bundle params = new Bundle();
                params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
                //dsp 芯片触发I帧
                mediaCodec.setParameters(params);
                timeStamp = System.currentTimeMillis();
            }
            try {
                MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 100000);
                Log.i(TAG, "outputBufferIndex: " + outputBufferIndex);

                if (outputBufferIndex >= 0) {
                    if (startTime == 0) {
                        startTime = bufferInfo.presentationTimeUs / 1000;
                    }
                    ByteBuffer buffer = mediaCodec.getOutputBuffer(outputBufferIndex);
                    byte[] outData = new byte[bufferInfo.size];
                    buffer.get(outData);
                    RTMPPackage rtmpPackage = new RTMPPackage(outData, (bufferInfo.presentationTimeUs / 1000) - startTime);
                    bitmapLive.addPackage(rtmpPackage);
                    mediaCodec.releaseOutputBuffer(outputBufferIndex, false);

                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            } catch (Exception e) {
                Log.d(TAG, "run: " + e.getMessage());
            }
        }
        isRunning = false;
        mediaCodec.stop();
        mediaCodec.release();
        mediaCodec = null;
        startTime = 0;
    }
}